package com.ticket.common.utils.wechat;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ticket.common.enums.HttpRequestMethod;
import com.ticket.common.utils.wechat.sdk.MyX509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;


public class HttpsRequestUtils {
	private static Logger LOGGER = LoggerFactory.getLogger(HttpsRequestUtils.class);
	
	/**
	 * 发起https GET请求并获取结果
	 * @param requestUrl 请求地址
	 * @return
	 */
	public static JSONObject get(String requestUrl) {
		return request(requestUrl, HttpRequestMethod.GET.name(), null);
	}
	
	/**
	 * 发起https GET请求并获取结果
	 * @param requestUrl 请求地址
	 * @return
	 */
	public static byte[] getBytes(String requestUrl) {
		// System.out.println("GET.bytes---" + requestUrl);
		return requestBytes(requestUrl, HttpRequestMethod.GET.name(), null);
	}
	
	/**
	 * 发起https POST请求并获取结果
	 * @param requestUrl 请求地址
	 * @param postJson	提交的数据
	 * @return
	 */
	public static JSONObject post(String requestUrl, String postJson) {
		return request(requestUrl, HttpRequestMethod.POST.name(), postJson); 
	}
	
	/**
	 * 发起https POST请求并获取结果
	 * @param requestUrl 请求地址
	 * @return
	 */
	public static byte[] postBytes(String requestUrl, byte[] requestBytes) {
		// System.out.println("POST.bytes---" + requestUrl);
		return requestBytes(requestUrl, HttpRequestMethod.POST.name(), requestBytes); 
	}
	
	/**
	 * 发起https请求并获取结果
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式
	 * @param requestJson 提交的数据
	 * @return JSONObject
	 */
	private static JSONObject request(String requestUrl, String requestMethod, String requestJson) {
		JSONObject jsonObject = new JSONObject();
		try {
			// 创建SSLContext对象，并使用我们指定的信任的管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
			urlConnection.setSSLSocketFactory(ssf);

			urlConnection.setDoOutput(true);
			urlConnection.setDoInput(true);
			urlConnection.setUseCaches(false);
			// 设置请求方式（GET/POST）
			urlConnection.setRequestMethod(requestMethod);

			if (HttpRequestMethod.GET.name().equalsIgnoreCase(requestMethod)) {
				urlConnection.connect();
			}
			// 当有数据需要提交时
			if (null != requestJson) {
				OutputStream outputStream = urlConnection.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(requestJson.getBytes("UTF-8"));
				outputStream.flush();
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = urlConnection.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

			String line = null;
			StringBuffer buffer = new StringBuffer();
			while ((line = bufferedReader.readLine()) != null) {
				buffer.append(line);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			urlConnection.disconnect();
			String responseDataString = buffer.toString();
			LOGGER.debug("request:"+responseDataString);
			if (responseDataString.length() > 0) {
				jsonObject = JSON.parseObject(buffer.toString());
			}
		} catch (MalformedURLException mue) {
			LOGGER.error("-----------------MalformedURLException！ ", mue);
		} catch (NoSuchAlgorithmException nsae) {
			LOGGER.error("-----------------NoSuchAlgorithmException！ ", nsae);
		} catch (NoSuchProviderException nspe) {
			LOGGER.error("-----------------NoSuchProviderException！ ", nspe);
		} catch (KeyManagementException kme) {
			LOGGER.error("-----------------KeyManagementException！ ", kme);
		} catch (UnsupportedEncodingException uee) {
			LOGGER.error("-----------------UnsupportedEncodingException！ ", uee);
		} catch (ProtocolException pe) {
			LOGGER.error("-----------------ProtocolException！ ", pe);
		} catch (IOException e) {
			LOGGER.error("-----------------Exception！ ", e);
		} finally {
			// ...
		}
		return jsonObject;
	}

	/**
	 * 发起https请求并获取字节数组结果
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式
	 * @param requestBytes 提交的二进制字节数据
	 * @return
	 */
	private static byte[] requestBytes(String requestUrl, String requestMethod, byte[] requestBytes) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			StringBuffer requestUrlBuffer = new StringBuffer(requestUrl);
			if (HttpRequestMethod.GET.name() == requestMethod && requestBytes != null && requestBytes.length > 0) {
				if (requestUrl.indexOf("?") >= 0) {
					requestUrlBuffer.append("&");
				} else {
					requestUrlBuffer.append("?");
				}
				requestUrlBuffer.append(new String(requestBytes));
			}
			System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
			URL url = new URL(requestUrlBuffer.toString());
			HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
			httpUrlConn.setDoInput(true);
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setRequestProperty("Content-length", "0");
			
			if (httpUrlConn instanceof HttpsURLConnection) {
				// 创建SSLContext对象，并使用我们指定的信任的管理器初始化
				TrustManager[] tm = { new MyX509TrustManager() };
				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
				sslContext.init(null, tm, new SecureRandom());
				// 从上述SSLContext对象中得到SSLSocketFactory对象
				SSLSocketFactory ssf = sslContext.getSocketFactory();
				((HttpsURLConnection) httpUrlConn).setSSLSocketFactory(ssf);
			}
			boolean truePost = (HttpRequestMethod.POST.name().equalsIgnoreCase(requestMethod) && requestBytes != null && requestBytes.length > 0);
			httpUrlConn.setDoOutput(truePost);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if (HttpRequestMethod.GET.name().equalsIgnoreCase(requestMethod)) {
				httpUrlConn.connect();
			} else if (truePost) {
				// 提交数据
				OutputStream outputStream = httpUrlConn.getOutputStream();
				outputStream.write(requestBytes);
				outputStream.close();
			}

			// 读取返回数据
			InputStream inputStream = httpUrlConn.getInputStream();
			byte[] buf = new byte[1024 * 2];
			int len;
			while ((len = inputStream.read(buf)) != -1) {
				out.write(buf, 0, len);
			}
			// 释放资源
			out.close();
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
		} catch (MalformedURLException mue) {
			// mue.printStackTrace();
			LOGGER.error("-----------------MalformedURLException！ ", mue);
		} catch (NoSuchAlgorithmException nsae) {
			// nsae.printStackTrace();
			LOGGER.error("-----------------NoSuchAlgorithmException！ ", nsae);
		} catch (NoSuchProviderException nspe) {
			// nspe.printStackTrace();
			LOGGER.error("-----------------NoSuchProviderException！ ", nspe);
		} catch (KeyManagementException kme) {
			// kme.printStackTrace();
			LOGGER.error("-----------------KeyManagementException！ ", kme);
		} catch (UnsupportedEncodingException uee) {
			// uee.printStackTrace();
			LOGGER.error("-----------------UnsupportedEncodingException！ ", uee);
		} catch (ProtocolException pe) {
			// pe.printStackTrace();
			LOGGER.error("-----------------ProtocolException！ ", pe);
		} catch (IOException e) {
			// e.printStackTrace();
			LOGGER.error("-----------------Exception！ ", e);
		} finally {
			// ...
		}
		return out.toByteArray();
	}
	
	public static String sendGet(String url) {
        String result = "";  
        BufferedReader in = null;  
        try {  
            URL realUrl = new URL(url);  
            // 打开和URL之间的连接  
            URLConnection connection = realUrl.openConnection();  
            // 设置通用的请求属性  
            connection.setRequestProperty("accept", "*/*");  
            connection.setRequestProperty("connection", "Keep-Alive");  
            connection.setRequestProperty("user-agent",  
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");  
            // 建立实际的连接  
            connection.connect();  
            // 定义 BufferedReader输入流来读取URL的响应  
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream(), "UTF-8"));  
            String line;  
            while ((line = in.readLine()) != null) {  
                result += line;  
            }  
        } catch (Exception e) {  
        	LOGGER.error("发送GET请求出现异常！" + e);  
        }  
        // 使用finally块来关闭输入流  
        finally {  
            try {  
                if (in != null) {  
                    in.close();  
                }  
            } catch (Exception e2) {  
                e2.printStackTrace();  
            }  
        }  
        return result;  
    }
}